package com.ctshk.rpc.visa.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.DateUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.booking.enums.SupplierReserveTypeEnum;
import com.ctshk.rpc.booking.req.system.visa.add.SupplierOrderSystemVisaAddReq;
import com.ctshk.rpc.booking.req.system.visa.add.SupplierSystemOrderVisaAddReq;
import com.ctshk.rpc.booking.req.system.visa.add.SupplierSystemOrderVisaDetailAddReq;
import com.ctshk.rpc.booking.service.ISupplierOrderService;
import com.ctshk.rpc.finance.json.FileJson;
import com.ctshk.rpc.finance.req.bill.BillAddCollectionReq;
import com.ctshk.rpc.finance.service.IFinanceBillService;
import com.ctshk.rpc.system.dto.MainDataCurrencyQueryDTO;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.req.MainDataCurrencyUpdateStatusReq;
import com.ctshk.rpc.system.service.IMainDataCurrencyService;
import com.ctshk.rpc.system.service.ISysSupplierService;
import com.ctshk.rpc.system.service.ISysUserService;
import com.ctshk.rpc.visa.dto.visa.VisaOrderCollectionDTO;
import com.ctshk.rpc.visa.entity.*;
import com.ctshk.rpc.visa.mapper.*;
import com.ctshk.rpc.visa.req.visa.VisaOrdercollectionConfirmationReq;
import com.ctshk.rpc.visa.req.visa.VisaOrdercollectionReq;
import com.ctshk.rpc.visa.service.IVisaOrderCollectionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

/**
 * <p>
 * 收款明细 服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-01-28
 */
@Slf4j
@DubboService
public class VisaOrderCollectionServiceImpl extends ServiceImpl<VisaOrderCollectionMapper, VisaOrderCollection> implements IVisaOrderCollectionService {
    @Autowired
    private VisaOrderTouristMapper visaOrderTouristMapper;
    @Autowired
    private VisaOrderMapper visaOrderMapper;

    @Autowired
    private VisaProductMapper visaProductMapper;

    @Autowired
    private VisaMapper visaMapper;

    @Autowired
    private VisaTypeMapper visaTypeMapper;

    @DubboReference
    private IMainDataCurrencyService iMainDataCurrencyService;

    @DubboReference
    IFinanceBillService financeBillService;

    @Autowired
    private VisaOrderCollectionMapper visaOrderCollectionMapper;
    @DubboReference
    private ISysUserService iSysUserService;

    @DubboReference
    private ISupplierOrderService supplierOrderService;

    @DubboReference
    private ISysSupplierService sysSupplierService;

    @Override
//    @GlobalTransactional(rollbackFor = Exception.class)
    public Long add(VisaOrdercollectionReq visaOrdercollectionReq, TokenUser user) throws BusinessException {

        QueryWrapper<VisaOrder> visaOrderQueryWrapper = new QueryWrapper<>();
        visaOrderQueryWrapper.eq("id", visaOrdercollectionReq.getId());
        visaOrderQueryWrapper.eq("is_deleted", 0);
        // 获取签证订单
        VisaOrder visaOrder = visaOrderMapper.selectOne(visaOrderQueryWrapper);
        if (visaOrder == null) {
            // 訂單不存在
            throw new BusinessException(SystemError.VISA_ORDER_25005);
        }

        // 金额判断
        if (visaOrdercollectionReq.getCollectionAmount() != null && visaOrdercollectionReq.getReceivableAmount() != null) {
            boolean flag = visaOrdercollectionReq.getCollectionAmount().compareTo(visaOrdercollectionReq.getReceivableAmount()) == -1;
            if (flag) {
                throw new BusinessException(SystemError.VISA_ORDER_25001);
            }
        } else {
            if (visaOrdercollectionReq.getCollectionAmount() == null) {
                throw new BusinessException(SystemError.VISA_ORDER_25002);
            } else if (visaOrdercollectionReq.getReceivableAmount() == null) {
                throw new BusinessException(SystemError.VISA_ORDER_25003);
            }
        }

        QueryWrapper<VisaOrderTourist> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", visaOrdercollectionReq.getId());
        List<VisaOrderTourist> visaOrderTouristList = visaOrderTouristMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(visaOrderTouristList)) {
            // 旅客列表不存在
            throw new BusinessException(SystemError.VISA_ORDER_25007);
        }

        // 获取签证产品
        QueryWrapper<VisaProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", visaOrder.getProductId());
        VisaProduct visaProduct = visaProductMapper.selectOne(queryWrapper);
        if (visaProduct == null) {
            throw new BusinessException(SystemError.VISA_ORDER_25012);
        }

        // 获取签证资源
        QueryWrapper<Visa> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("id", visaProduct.getVisaId());
        Visa visa = visaMapper.selectOne(wrapper1);
        if (visa == null) {
            throw new BusinessException(SystemError.VISA_ORDER_25005);
        }

        // 获取签证类型
        QueryWrapper<VisaType> wrapper3 = new QueryWrapper<>();
        wrapper3.eq("visa_id", visaProduct.getVisaId());
        wrapper3.eq("id",visaOrder.getTypeId());
        VisaType visaType = visaTypeMapper.selectOne(wrapper3);
        if (visaType == null) {
            throw new BusinessException(SystemError.VISA_ORDER_25013);
        }

        List<VisaOrderCollection> list = new ArrayList<>();
        // 收款明细存储
        for (VisaOrderTourist visaOrderTourist : visaOrderTouristList) {
            if (null != visaOrdercollectionReq.getVisaOrderCollectionListList() && visaOrdercollectionReq.getVisaOrderCollectionListList().size() > 0) {
                for (int i = 0; i < visaOrdercollectionReq.getVisaOrderCollectionListList().size(); i++) {
                    VisaOrderCollection visaOrderCollection = new VisaOrderCollection();
                    visaOrderCollection.setCreateId(user.getId());
                    visaOrderCollection.setCollectionAmount(visaOrdercollectionReq.getVisaOrderCollectionListList().get(i).getCollectionAmount());
                    visaOrderCollection.setCurrency(visaOrdercollectionReq.getVisaOrderCollectionListList().get(i).getCurrency());
                    visaOrderCollection.setCurrencyId(visaOrdercollectionReq.getVisaOrderCollectionListList().get(i).getCurrencyId());
                    visaOrderCollection.setOrderId(visaOrder.getId());
                    visaOrderCollection.setCollectionWay(visaOrdercollectionReq.getVisaOrderCollectionListList().get(i).getCollectionWay());
                    visaOrderCollection.setCollectionWayId(visaOrdercollectionReq.getVisaOrderCollectionListList().get(i).getCollectionWayId());
                    visaOrderCollection.setRemark(visaOrdercollectionReq.getVisaOrderCollectionListList().get(i).getRemark());
                    visaOrderCollection.setCollectionCertificateJson(visaOrdercollectionReq.getVisaOrderCollectionListList().get(i).getCollectionCertificateJson());
                    visaOrderCollection.setPayer(visaOrdercollectionReq.getVisaOrderCollectionListList().get(i).getPayer());
                    visaOrderCollection.setTouristName(visaOrderTourist.getSurname() + " " + visaOrderTourist.getName());
                    visaOrderCollection.setTouristId(visaOrderTourist.getId());
                    visaOrderCollection.setGmtCreate(LocalDateTime.now());
//                    visaOrderCollection.setOrderId(visaOrderTourist.getOrderId());
                    visaOrderCollection.setReceivableAmount(visaOrder.getTotalAmount());
                    //全款
                    visaOrderCollection.setCollectionType(1);
                    visaOrderCollection.setIsDeleted(0);
                    //收款单号  SKD+年後2位+月日4位+時分秒6位+2位隨機數字
                    Calendar now = Calendar.getInstance();
                    int hour = now.get(Calendar.HOUR_OF_DAY);
                    int minute = now.get(Calendar.MINUTE);
                    int second = now.get(Calendar.SECOND);
                    //时分秒字符串
                    String code = String.valueOf(hour) + String.valueOf(minute) + String.valueOf(second);
                    String collectionNumber = "SDK" + DateUtil.fmtNum(LocalDate.now()) + code + RandomUtil.randomNumbers(2);
                    visaOrderCollection.setCollectionNumber(collectionNumber);
                    if (visaOrdercollectionReq.getUsingGroup() != null) {
                        visaOrderCollection.setUsingGroup(visaOrdercollectionReq.getUsingGroup());
                    }
                    list.add(visaOrderCollection);
                }
            }
        }

        /**
         * 自由行预订-签证新增(自由行付款专用)
         */
        generatorSupplierBooking(visaProduct, visaOrderTouristList, visaOrder, user.getId(), visa, visaType);

        /**
         * 生成财务收款记录
         */
        generatorFinance(user.getId(), visaOrder, visa, list);

        visaOrder.setBookingStatus(4);
        visaOrder.setCancelStatus(0);
        visaOrder.setStatus(2);
        visaOrderMapper.updateById(visaOrder);

        visaOrderCollectionMapper.insertBatchSomeColumn(list);
        return visaOrder.getId();
    }


    private void generatorSupplierBooking(VisaProduct visaProduct, List<VisaOrderTourist> visaOrderTourists, VisaOrder visaOrder, Long userId, Visa visa, VisaType visaType) {
        SupplierOrderSystemVisaAddReq supplierOrderSystemVisaAddReq = new SupplierOrderSystemVisaAddReq();
        // 生成供应预订单
        UserDTO chargeUser = iSysUserService.queryCacheUser(userId);
        supplierOrderSystemVisaAddReq.setSupplierId(visaType.getSupplierId()); // 供应商ID
        supplierOrderSystemVisaAddReq.setSupplierName(visaType.getSupplierName());//供应商名称
        // todo 办理时内部挂账待完成
        supplierOrderSystemVisaAddReq.setSupplierOrderType("1"); //供应商订单类型
        supplierOrderSystemVisaAddReq.setOriginalSaleNumber(null);//供应商销售编号/部门ID
        supplierOrderSystemVisaAddReq.setBusinessType(SystemBusinessType.VISA.getCode());// 业务类型
        supplierOrderSystemVisaAddReq.setSaleType(SalesMethod.SINGLE_SALE.getCode()); // 销售方式
        supplierOrderSystemVisaAddReq.setReserveTypeId(SupplierReserveTypeEnum.VISA.getId()); // 签证类型
        supplierOrderSystemVisaAddReq.setProductType(ProductType.MANUAL_ENTRY.getCode()); // 产品类型
        supplierOrderSystemVisaAddReq.setDepartmentId(chargeUser.getDeptId()); // 资源所属部门ID
        supplierOrderSystemVisaAddReq.setDepartment(chargeUser.getDept()); // 所属部门
        supplierOrderSystemVisaAddReq.setSaleNumber(visaOrder.getOrderNumber()); // 销售单号
        supplierOrderSystemVisaAddReq.setProductNumber(visa.getId().toString()); // 产品编号
        supplierOrderSystemVisaAddReq.setProductName(visa.getName());  // 产品名称
        supplierOrderSystemVisaAddReq.setTotalFee(visaType.getCostAmount()); // 总成本金额
        supplierOrderSystemVisaAddReq.setCurrencyId(visaType.getCurrencyId()); // 币种id
        supplierOrderSystemVisaAddReq.setCurrency(visaType.getCurrency()); // 币种名称

        // todo 委托种类的成本金额
        supplierOrderSystemVisaAddReq.setPayableAmount(visaType.getCostAmount()); // 付款金额
        // todo 前端给的凭证
        supplierOrderSystemVisaAddReq.setFilesJson(null);
        supplierOrderSystemVisaAddReq.setConfirmStatus(OrderSubscribeStatus.CONFIRM.getCode());

        // 构建供应商预订-签证信息
        List<SupplierSystemOrderVisaAddReq> visaAddReqList = new ArrayList<>();
        SupplierSystemOrderVisaAddReq visaAddReq = new SupplierSystemOrderVisaAddReq();
        visaAddReq.setOrderId(visaOrder.getId());
        visaAddReq.setCustomerRemark("");
        ArrayList<SupplierSystemOrderVisaDetailAddReq> detailAddReqList = new ArrayList<>();
        SupplierSystemOrderVisaDetailAddReq req = new SupplierSystemOrderVisaDetailAddReq();
        // 国家名称
        req.setCountryName(visa.getCountryName());
        // 国家id
        req.setCountryId(visa.getCountryId());
        // 签证类型id
        req.setVisaId(visa.getId());
        // 签证名称
        req.setVisaName(visa.getName());
        // 有效次数
        req.setEffectiveFrequency(visa.getVaildTimes());
        // 委托种类id
        req.setEntrustTypeId(visaType.getTypeId());
        // 委托种类名称
        req.setEntrustTypeName(visaType.getTypeName());
        if (visaOrderTourists.size() > 0 && visaOrderTourists != null) {
            // 旅客数量
            req.setNumber(visaOrderTourists.size());
            for (VisaOrderTourist orderTourist : visaOrderTourists) {
                // 旅客名称
                if (req.getPassengerName() == null) {
                    req.setPassengerName("");
                }
                req.setPassengerName(req.getPassengerName().concat("," + orderTourist.getSurname() + orderTourist.getName()));
            }
        }

        BigDecimal price = new BigDecimal("0");
        // 单价
//        if (visaProduct.getAdjustType() == 1) {
//            // 加数值
//            price.add(visaType.getCostAmount());
//            req.setPrice(price);
//        } else if (visaProduct.getAdjustType() == 2) {
//            // 加百分比
//            req.setPrice(visaType.getCostAmount().multiply(new BigDecimal(visaProduct.getPercent())).divide(new BigDecimal("100")));
//        }
        req.setPrice(visaType.getCostAmount());
        detailAddReqList.add(req);
        visaAddReq.setSupplierSystemOrderVisaDetailAddReqList(detailAddReqList);
        visaAddReqList.add(visaAddReq);
        supplierOrderSystemVisaAddReq.setSupplierSystemOrderVisaAddReqList(visaAddReqList);
        supplierOrderService.addSystemVisa(supplierOrderSystemVisaAddReq, userId);
    }

    private void generatorFinance(Long userId, VisaOrder visaOrder, Visa visa, List<VisaOrderCollection> visaOrderCollections) {
        List<BillAddCollectionReq> billAddCollectionReqs = new ArrayList<>();
        for (VisaOrderCollection visaOrderCollection : visaOrderCollections) {
            List<FileJson> fileJsons = JSON.parseArray(visaOrderCollection.getCollectionCertificateJson(), FileJson.class);
            UserDTO userDTOTemp = iSysUserService.queryCacheUser(visaOrder.getCreateId());
            BillAddCollectionReq billAddCollectionReq = new BillAddCollectionReq();
            billAddCollectionReqs.add(billAddCollectionReq);
            billAddCollectionReq.setBillNumber(visaOrderCollection.getCollectionNumber());
            billAddCollectionReq.setBusinessType(SystemBusinessType.VISA.getCode());
            billAddCollectionReq.setCollectionWayId(visaOrderCollection.getCollectionWayId());
            billAddCollectionReq.setCollectionWayName(visaOrderCollection.getCollectionWay());
            billAddCollectionReq.setCollectionTypeId(CollectionTypeIdCode.FULL.getCode());
            billAddCollectionReq.setCollectionTypeName(CollectionTypeIdCode.FULL.getMsg());
            billAddCollectionReq.setCollectionAmount(visaOrderCollection.getCollectionAmount());
            billAddCollectionReq.setCurrencyId(visaOrderCollection.getCurrencyId());
            billAddCollectionReq.setCurrencyName(visaOrderCollection.getCurrency());
            MainDataCurrencyUpdateStatusReq dataCurrencyUpdateStatusReq = new MainDataCurrencyUpdateStatusReq();
            dataCurrencyUpdateStatusReq.setId(visaOrderCollection.getCurrencyId());
            Result<MainDataCurrencyQueryDTO> query = iMainDataCurrencyService.query(dataCurrencyUpdateStatusReq);
            billAddCollectionReq.setExchangeRate(query.getData().getMarketExchangeRate().doubleValue());
//            billAddCollectionReq.setExchangeRate(new Double(1));
            billAddCollectionReq.setCollectionTime(visaOrderCollection.getGmtCreate());
            billAddCollectionReq.setCollectionVoucherJsonList(fileJsons); // 收款凭证
            billAddCollectionReq.setSaleOrderNumber(visaOrder.getOrderNumber());
            billAddCollectionReq.setSaleOrderId(visaOrder.getId());
            // todo 产品id和编号缺少两个备注
            billAddCollectionReq.setProductId(Arrays.asList(visa.getId()));
            billAddCollectionReq.setProductNumber(visa.getId().toString());
            billAddCollectionReq.setProductName(visa.getName());
            billAddCollectionReq.setResourceInfo(Arrays.asList(visa.getName()));
            billAddCollectionReq.setSaleUserId(userDTOTemp.getId());
            billAddCollectionReq.setSaleUserName(userDTOTemp.getFullName());
            billAddCollectionReq.setSaleDeptId(userDTOTemp.getDeptId());
            billAddCollectionReq.setUserId(userId);
            log.info("【签证订单】生成财务收款记录, req:{}", JSON.toJSONString(billAddCollectionReqs));
            financeBillService.addCollection(billAddCollectionReqs);
        }
    }

    @Override
    public Result<List<VisaOrderCollectionDTO>> list(VisaOrdercollectionReq visaOrdercollectionReq) {
        List<VisaOrderCollectionDTO> visaOrderCollectionDTOList = new ArrayList<>();
        QueryWrapper<VisaOrderCollection> visaOrderCollectionQueryWrapper = new QueryWrapper<>();
        visaOrderCollectionQueryWrapper.eq("order_id", visaOrdercollectionReq.getOrderId());
        visaOrderCollectionQueryWrapper.eq("is_deleted", 0);
        List<VisaOrderCollection> visaOrderCollectionList = visaOrderCollectionMapper.selectList(visaOrderCollectionQueryWrapper);
        if (visaOrderCollectionList != null && visaOrderCollectionList.size() >= 1) {
            for (VisaOrderCollection visaOrderCollection : visaOrderCollectionList) {
                VisaOrderCollectionDTO visaOrderCollectionDTO = EntityUtil.copy(visaOrderCollection, VisaOrderCollectionDTO.class);
                UserDTO userDTO = null;
                try {
                    userDTO = iSysUserService.loadUserByParam(visaOrderCollection.getCreateId(), 1);
                    visaOrderCollectionDTO.setCreateByName(userDTO.getCnSurname() + userDTO.getCnName() + "/" + userDTO.getDept());
                } catch (Exception e) {
                    throw new BusinessException(SystemError.SYS_502);
                }
                visaOrderCollectionDTOList.add(visaOrderCollectionDTO);
            }
        }
        return Result.success(visaOrderCollectionDTOList);
    }

    @Override
    public Result<Long> confirmation(VisaOrdercollectionConfirmationReq confirmationReq, TokenUser user) {
        VisaOrderCollection visaOrderCollection = visaOrderCollectionMapper.selectById(confirmationReq.getId());
        visaOrderCollection.setStatus(2);
        visaOrderCollection.setGmtModified(LocalDateTime.now());
        visaOrderCollection.setModifiedId(user.getId());
        visaOrderCollectionMapper.updateById(visaOrderCollection);
        return Result.success(visaOrderCollection.getId());
    }
}
